home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
intrvews
/
examples.lha
/
examples
/
rubberband.C
Wrap
C/C++ Source or Header
|
1993-07-24
|
4KB
|
154 lines
// From linton@marktwain.rad.sgi.com (Mark Linton)
// Subject: rubberbanding
// Date: Tue, 21 Jul 1992 18:00:37 GMT
//
// Several people have asked about rubberbanding. Below is an example
// of a way to do rubberbanding while allowing double-buffering.
// The approach is to have a monoglyph (Selector in the example)
// that assumes its contents are opaque and do not change while rubberbanding
// (the latter restriction could be lifted so long as there was an explicit
// notification that the contents changed). The example also could be optimized
// a bit by having Selector::drag damage the old and new areas instead
// of damaging the entire area via redraw.
#include <IV-look/kit.h>
#include <InterViews/brush.h>
#include <InterViews/color.h>
#include <InterViews/display.h>
#include <InterViews/event.h>
#include <InterViews/image.h>
#include <InterViews/input.h>
#include <InterViews/layout.h>
#include <InterViews/raster.h>
#include <InterViews/tiff.h>
#include <InterViews/session.h>
#include <InterViews/style.h>
#include <InterViews/transformer.h>
#include <InterViews/tformsetter.h>
#include <InterViews/window.h>
#include <stdio.h>
#include <stdlib.h>
class Selector : public InputHandler {
public:
Selector(Glyph*, Style*);
virtual ~Selector();
virtual void draw(Canvas*, const Allocation&) const;
virtual void press(const Event&);
virtual void drag(const Event&);
virtual void release(const Event&);
private:
Brush* brush_;
Color* color_;
Coord x0_;
Coord y0_;
Coord x1_;
Coord y1_;
Coord x2_;
Coord y2_;
boolean drawn_;
boolean overlay_damage_;
boolean overlay_done_;
};
Selector::Selector(Glyph* g, Style* s) : InputHandler(g, s) {
brush_ = new Brush(0);
Resource::ref(brush_);
color_ = new Color(*WidgetKit::instance()->background(), 1.0, Color::Xor);
Resource::ref(color_);
drawn_ = false;
overlay_damage_ = false;
overlay_done_ = false;
}
Selector::~Selector() {
Resource::unref(brush_);
Resource::unref(color_);
}
void Selector::draw(Canvas* c, const Allocation& a) const {
if (overlay_damage_) {
Transformer identity;
c->push_transform();
c->transformer(identity);
if (drawn_) {
c->rect(x0_, y0_, x1_, y1_, color_, brush_);
}
Selector* s = (Selector*)this;
if (overlay_done_) {
s->drawn_ = false;
s->overlay_damage_ = false;
s->overlay_done_ = false;
} else {
c->rect(x0_, y0_, x2_, y2_, color_, brush_);
s->x1_ = s->x2_;
s->y1_ = s->y2_;
s->drawn_ = true;
}
c->pop_transform();
} else {
InputHandler::draw(c, a);
}
}
void Selector::press(const Event& e) {
x0_ = e.pointer_x();
y0_ = e.pointer_y();
InputHandler::press(e);
}
void Selector::drag(const Event& e) {
x2_ = e.pointer_x();
y2_ = e.pointer_y();
overlay_damage_ = true;
redraw();
}
void Selector::release(const Event& e) {
overlay_damage_ = true;
overlay_done_ = true;
redraw();
InputHandler::release(e);
}
static PropertyData props[] = {
// { "*visual", "TrueColor" },
{ nil }
};
static OptionDesc options[] = {
{ nil }
};
int main(int argc, char** argv) {
Session* session = new Session("Ipaste", argc, argv, options, props);
if (argc == 1) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
exit(1);
}
Raster* rast = TIFFRaster::load(argv[1]);
if (rast == nil) {
fprintf(stderr, "%s: open tiff image %s failed\n", argv[0], argv[1]);
exit(1);
}
Style* style = session->default_display()->style();
const LayoutKit& layout = *LayoutKit::instance();
session->run_window(
new ApplicationWindow(
layout.flexible(
new Selector(
new TransformFitter(new Image(rast)), style
)
)
)
);
}